﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit.Electric.Common;
using HYRElectric.PowerSystem;
using HYView;

namespace HYRElectric.Equipment
{
	public class EquipmentLayoutCmdEntry
	{
		public EquipmentLayoutCmdEntry(ExternalCommandData data, EquipmentType type)
		{
			this.m_data = data;
			this.uiApp = data.Application;
			this.docUI = this.uiApp.ActiveUIDocument;
			this.doc = this.docUI.Document;
			this.equipmentType = type;
			this.BindDataToEquipmentType();
		}

		public List<BuiltInCategory> GetCategoryFilters()
		{
			return this.categoryFilters;
		}

		public Dictionary<string, List<Family>> GetFamilyListFromCurDoc()
		{
			Dictionary<BuiltInCategory, string> dictionary = new Dictionary<BuiltInCategory, string>();
			switch (this.equipmentType)
			{
			case EquipmentType.Lamp:
				dictionary.Add(BuiltInCategory.OST_LightingFixtures, "灯具");
				break;
			case EquipmentType.Switch:
				dictionary.Add(BuiltInCategory.OST_LightingDevices, "开关");
				break;
			case EquipmentType.Socket:
				dictionary.Add(BuiltInCategory.OST_ElectricalFixtures, "插座");
				break;
			case EquipmentType.SwitchBox:
				dictionary.Add(BuiltInCategory.OST_ElectricalEquipment, "配电箱");
				break;
			case EquipmentType.Power:
				dictionary.Add(BuiltInCategory.OST_ElectricalFixtures, "动力");
				break;
			case EquipmentType.FireDetector:
				dictionary.Add(BuiltInCategory.OST_FireAlarmDevices, "探测器");
				break;
			case EquipmentType.FireAlarm:
				dictionary.Add(BuiltInCategory.OST_FireAlarmDevices, "消防报警");
				break;
			case EquipmentType.Radio:
				dictionary.Add(BuiltInCategory.OST_CommunicationDevices, "广播");
				break;
			case EquipmentType.Security:
				dictionary.Add(BuiltInCategory.OST_SecurityDevices, "安防");
				break;
			case EquipmentType.Cabling:
				dictionary.Add(BuiltInCategory.OST_CommunicationDevices, "通讯设备");
				dictionary.Add(BuiltInCategory.OST_DataDevices, "数据设备");
				dictionary.Add(BuiltInCategory.OST_NurseCallDevices, "护理呼叫设备");
				dictionary.Add(BuiltInCategory.OST_TelephoneDevices, "电话设备");
				break;
			case EquipmentType.SwitchBoxes:
				dictionary.Add(BuiltInCategory.OST_ElectricalEquipment, "配电柜");
				break;
			case EquipmentType.Transformer:
				dictionary.Add(BuiltInCategory.OST_ElectricalEquipment, "变压器");
				break;
			}
			Dictionary<string, List<Family>> dictionary2 = new Dictionary<string, List<Family>>();
			foreach (KeyValuePair<BuiltInCategory, string> keyValuePair in dictionary)
			{
				BuiltInCategory key = keyValuePair.Key;
				string value = keyValuePair.Value;
				List<Family> list = new List<Family>();
				foreach (Element element in new FilteredElementCollector(this.doc).OfClass(typeof(FamilySymbol)).OfCategory(key).ToElements())
				{
					FamilySymbol familySymbol = element as FamilySymbol;
					if (!list.Contains(familySymbol.Family, new FamilyIdComparer()))
					{
						string name = familySymbol.Family.Name;
						switch (this.equipmentType)
						{
						case EquipmentType.Socket:
							if (name.IndexOf("插座") < 0)
							{
								continue;
							}
							break;
						case EquipmentType.SwitchBox:
							if (name.IndexOf("配电箱") < 0)
							{
								continue;
							}
							break;
						case EquipmentType.Power:
							if (name.IndexOf("插座") >= 0)
							{
								continue;
							}
							break;
						case EquipmentType.FireDetector:
							if (name.IndexOf("探测器") < 0)
							{
								continue;
							}
							break;
						case EquipmentType.FireAlarm:
							if (name.IndexOf("探测器") >= 0)
							{
								continue;
							}
							break;
						case EquipmentType.SwitchBoxes:
							if (name.IndexOf("配电柜") < 0)
							{
								continue;
							}
							break;
						case EquipmentType.Transformer:
							if (name.IndexOf("变压器") < 0)
							{
								continue;
							}
							break;
						}
						list.Add(familySymbol.Family);
					}
				}
				dictionary2.Add(value, list);
			}
			return dictionary2;
		}

		public bool StartCommand()
		{
			this.BindDataToEquipmentType();
			FamilyLibDataAssist familyLibDataAssist = new FamilyLibDataAssist(this.doc, this.dbTableName);
			List<DbFamilyObject> familyObjects = familyLibDataAssist.LoadFamilyDatas(null);
			List<DbFamilyGroup> groups = this.GroupByImage2D(familyObjects);
			Dictionary<string, List<Family>> familyListFromCurDoc = this.GetFamilyListFromCurDoc();
			EquipmentLayoutFormNew equipmentLayoutFormNew = new EquipmentLayoutFormNew(this.formTitle, this.dbTableName, groups, this.layoutWays, familyListFromCurDoc, this.uiApp, false);
			if (equipmentLayoutFormNew.ShowDialog() == DialogResult.OK)
			{
				EquipmentLayoutWay layoutWay = equipmentLayoutFormNew.LayoutWay;
				DbFamilyObject familyObject = equipmentLayoutFormNew.FamilyObject;
				FamilySymbol selectedFamilySymbol = equipmentLayoutFormNew.SelectedFamilySymbol;
				if (equipmentLayoutFormNew.bIsFamilyLib)
				{
					familyLibDataAssist.SetFamilyDatas(familyObject);
				}
				EquipmentLayout equipmentLayout = null;
				if (layoutWay <= EquipmentLayoutWay.Lay_RectEx)
				{
					switch (layoutWay)
					{
					case EquipmentLayoutWay.Lay_Random:
						equipmentLayout = new RandomLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
						break;
					case EquipmentLayoutWay.Lay_DragLine:
						equipmentLayout = new DragLineLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
						break;
					case (EquipmentLayoutWay)3:
						break;
					case EquipmentLayoutWay.Lay_DragLineEx:
						equipmentLayout = new DragLineExLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
						break;
					default:
						if (layoutWay != EquipmentLayoutWay.Lay_Rect)
						{
							if (layoutWay == EquipmentLayoutWay.Lay_RectEx)
							{
								equipmentLayout = new RectLayoutEx(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
							}
						}
						else
						{
							equipmentLayout = new RectLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
						}
						break;
					}
				}
				else if (layoutWay != EquipmentLayoutWay.Lay_ArcLine)
				{
					if (layoutWay != EquipmentLayoutWay.Lay_Fan)
					{
						switch (layoutWay)
						{
						case EquipmentLayoutWay.Lay_SwitchBoxes:
							equipmentLayout = new SwitchBoxesLayout(this.m_data, familyObject, selectedFamilySymbol, this.categoryFilters);
							break;
						case EquipmentLayoutWay.Lay_WallCross:
							if (!(this.doc.ActiveView is ViewPlan) && SwitchView.SetUsableView((HYView.CmdViewType)3, this.uiApp) != null)
							{
								return false;
							}
							equipmentLayout = new WallCrossLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
							break;
						case EquipmentLayoutWay.Lay_CenterRoom:
							equipmentLayout = new CenterRoomLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
							break;
						}
					}
					else
					{
						equipmentLayout = new FanLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
					}
				}
				else
				{
					equipmentLayout = new ArcLineLayout(this.docUI, this.doc, familyObject, selectedFamilySymbol, this.categoryFilters);
				}
				if (equipmentLayout != null)
				{
					return equipmentLayout.Layout();
				}
			}
			return false;
		}

		public DbFamilyObject GetSelectFamily(ref string strTypeName, ref EquipmentType defaultType)
		{
			this.m_dictEquipmentType.Clear();
			for (EquipmentType equipmentType = EquipmentType.Lamp; equipmentType <= EquipmentType.Cabling; equipmentType++)
			{
				this.equipmentType = equipmentType;
				this.BindDataToEquipmentType();
			}
			DlgEquipTypeSelect dlgEquipTypeSelect = new DlgEquipTypeSelect(this.m_dictEquipmentType, defaultType);
			if (dlgEquipTypeSelect.ShowDialog() != DialogResult.OK)
			{
				return null;
			}
			this.equipmentType = dlgEquipTypeSelect.m_selType;
			defaultType = dlgEquipTypeSelect.m_selType;
			this.BindDataToEquipmentType();
			FamilyLibDataAssist familyLibDataAssist = new FamilyLibDataAssist(this.doc, this.dbTableName);
			List<DbFamilyObject> familyObjects = familyLibDataAssist.LoadFamilyDatas(null);
			List<DbFamilyGroup> groups = this.GroupByImage2D(familyObjects);
			Dictionary<string, List<Family>> familyListFromCurDoc = this.GetFamilyListFromCurDoc();
			EquipmentLayoutFormNew equipmentLayoutFormNew = new EquipmentLayoutFormNew(this.formTitle, this.dbTableName, groups, this.layoutWays, familyListFromCurDoc, this.uiApp, true);
			int num = (int)equipmentLayoutFormNew.ShowDialog();
			DbFamilyObject dbFamilyObject = null;
			strTypeName = this.m_dictEquipmentType[this.equipmentType];
			if (num == 1)
			{
				EquipmentLayoutWay layoutWay = equipmentLayoutFormNew.LayoutWay;
				dbFamilyObject = equipmentLayoutFormNew.FamilyObject;
				if (equipmentLayoutFormNew.bIsFamilyLib)
				{
					familyLibDataAssist.SetFamilyDatas(dbFamilyObject);
				}
			}
			return dbFamilyObject;
		}

		private void BindDataToEquipmentType()
		{
			this.categoryFilters.Clear();
			switch (this.equipmentType)
			{
			case EquipmentType.Lamp:
				this.formTitle = "灯具";
				this.dbTableName = "Lamp";
				this.layoutWays = 127;
				this.categoryFilters.Add(BuiltInCategory.OST_LightingFixtures);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Switch:
				this.formTitle = "开关";
				this.dbTableName = "Switch";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_LightingDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Socket:
				this.formTitle = "插座";
				this.dbTableName = "Socket";
				this.layoutWays = 7;
				this.categoryFilters.Add(BuiltInCategory.OST_ElectricalFixtures);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.SwitchBox:
				this.formTitle = "配电箱";
				this.dbTableName = "SwitchBox";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_ElectricalEquipment);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Power:
				this.formTitle = "动力";
				this.dbTableName = "Power";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_ElectricalFixtures);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.FireDetector:
				this.formTitle = "探测器";
				this.dbTableName = "FireDetector";
				this.layoutWays = 127;
				this.categoryFilters.Add(BuiltInCategory.OST_FireAlarmDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.FireAlarm:
				this.formTitle = "消防报警";
				this.dbTableName = "FireAlarm";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_FireAlarmDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Radio:
				this.formTitle = "广播";
				this.dbTableName = "Radio";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_CommunicationDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Security:
				this.formTitle = "安防";
				this.dbTableName = "Security";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_SecurityDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Cabling:
				this.formTitle = "综合布线";
				this.dbTableName = "Cabling";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_DataDevices);
				this.categoryFilters.Add(BuiltInCategory.OST_CommunicationDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.SwitchBoxes:
				this.formTitle = "配电柜布置";
				this.dbTableName = "SwitchBoxes";
				this.layoutWays = 512;
				this.categoryFilters.Add(BuiltInCategory.OST_ElectricalEquipment);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Transformer:
				this.formTitle = "变压器";
				this.dbTableName = "Transformer";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_ElectricalEquipment);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.Communication:
				this.formTitle = "通信";
				this.dbTableName = "Communication";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_CommunicationDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			case EquipmentType.TV:
				this.formTitle = "有线电视";
				this.dbTableName = "TV";
				this.layoutWays = 1;
				this.categoryFilters.Add(BuiltInCategory.OST_DataDevices);
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
					return;
				}
				break;
			default:
				this.formTitle = "设备布置";
				this.dbTableName = "Other";
				this.layoutWays = 1;
				if (!this.m_dictEquipmentType.ContainsKey(this.equipmentType))
				{
					this.m_dictEquipmentType.Add(this.equipmentType, this.formTitle);
				}
				break;
			}
		}

		private List<DbFamilyGroup> GroupByImage2D(List<DbFamilyObject> familyObjects)
		{
			List<DbFamilyGroup> list = new List<DbFamilyGroup>();
			if (familyObjects == null)
			{
				return list;
			}
			using (List<DbFamilyObject>.Enumerator enumerator = familyObjects.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					DbFamilyObject item = enumerator.Current;
					if (string.IsNullOrEmpty(item.Image2D))
					{
						new DbFamilyGroup().FamilyObjects.Add(item);
					}
					else if (list.Exists((DbFamilyGroup u) => u.Image2D == item.Image2D))
					{
						list.Find((DbFamilyGroup u) => u.Image2D == item.Image2D).FamilyObjects.Add(item);
					}
					else
					{
						list.Add(new DbFamilyGroup
						{
							Image2D = item.Image2D,
							FamilyObjects = 
							{
								item
							}
						});
					}
				}
			}
			return list;
		}

		private UIApplication uiApp;

		private UIDocument docUI;

		private Document doc;

		private ExternalCommandData m_data;

		private EquipmentType equipmentType;

		private Dictionary<EquipmentType, string> m_dictEquipmentType = new Dictionary<EquipmentType, string>();

		private string formTitle = string.Empty;

		private string dbTableName = string.Empty;

		private int layoutWays;

		private List<BuiltInCategory> categoryFilters = new List<BuiltInCategory>();
	}
}
